/********************************************************************************
 * Copyright(c) 2020-2025 VINCENT_WY All rights reserved.
 * - Filename
 * - Author  Vincent
 * - Version V1.0.0
 * - Date    2023/09/21
 * - Brief
 * - FunctionList:
 ******************************************************************************
 * History:
 *
 *
 *
 ******************************************************************************
 */
#include "DispatchFileReader.hpp"
#include "TimeUtil.h"
#include "log.h"
#include <sys/time.h>
#include <sys/types.h>
#include <filesystem>
#include <string.h>
#include <dirent.h>
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

DispatchFileReader::DispatchFileReader(const std::string &root, const int &id) : _root(root), _id(id), TAG("DispatchFileReader" + id)
{
    LOGI(TAG, "start read file info....");
    LOGI(TAG, "input folder path: {}", root);
    _root = root;
    if (root.back() != '/')
    {
        _root.append("/");
    }
    _root.append("lidar_"+std::to_string(_id)+"/");
    DIR *pDir;
    struct dirent *ptr;
    if (!(pDir = opendir(_root.c_str())))
    {
        LOGE(TAG,"Folder doesn't Exist!");
        return;
    }
    std::map<uint64_t, DispatchFileInfo> m_dispatchFileMap;
    while ((ptr = readdir(pDir)) != 0)
    {
        if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
        {
            DispatchFileInfo mFileInfo;
            std::string mFileName = ptr->d_name;
            int nPos = mFileName.find(".pcd");
            if (nPos != std::string::npos && nPos == mFileName.length() - 4)
            {
                std::string freq = mFileName.substr(0, nPos);
                mFileInfo.fileName = _root+mFileName;
                mFileInfo.timestamp = std::stoll(freq);
                m_dispatchFileMap.insert(std::make_pair(mFileInfo.timestamp, mFileInfo));
            }
        }
    }
    closedir(pDir);
    for (auto &&it : m_dispatchFileMap)
    {
        _dispatchFileList.emplace_back(it.second);

        std::cout<< it.second.timestamp<<"   "<<it.second.fileName<<std::endl;
    }

    LOG_I(TAG, "end read file info,total file count: {}", _dispatchFileList.size());
}
DispatchFileReader::~DispatchFileReader()
{
    LOGI(TAG, "~~~~");
}
std::vector<DispatchFileInfo> DispatchFileReader::getFileInfoList()
{
    return _dispatchFileList;
}
std::shared_ptr<lpc::LidarProtoPointCloud> DispatchFileReader::getDispatchFrame(const DispatchFileInfo &file)
{
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
    if (pcl::io::loadPCDFile<pcl::PointXYZI>(file.fileName, *cloud) == -1)
    {
        LOG_E(TAG, "Could not read PCD file,file name {}", file.fileName);
        return nullptr;
    }
    auto frame = std::make_shared<lpc::LidarProtoPointCloud>();
    frame->set_lidar_id(_id);
    frame->set_system_timestamp(TimeUtil::now_ms());
    frame->set_timestamp((uint64_t)file.timestamp);
    frame->set_height(1);
    frame->set_is_dense(false);
    frame->set_width(cloud->points.size());
    for (size_t i = 0; i < cloud->points.size(); ++i)
    {
        frame->add_data(cloud->points[i].x);
        frame->add_data(cloud->points[i].y);
        frame->add_data(cloud->points[i].z);
        frame->add_data(cloud->points[i].intensity);
    }
    LOG_I(TAG, "id:{},frame time:{}, point count:{}", frame->lidar_id(), frame->timestamp(), frame->height() * frame->width());
    return frame;
}
